package com.pai4j.netty.gateway.router;

import com.alibaba.nacos.api.naming.pojo.Instance;
import com.pai4j.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


@Slf4j
public class RouterTable  {

    private static List<Instance> INSTANCES = new ArrayList<>();

    private static AtomicInteger rtCount = new AtomicInteger(0);

    /**
     * 更新本地路由表
     *
     * @param instances
     */
    public void doUpdate(List<Instance> instances) {
        INSTANCES = instances;
        log.info("netty service exchange ==> instances: {}", INSTANCES);
    }

    /**
     * 获取服务节点实例
     *
     * @param index
     * @return
     */
    public static Instance getInstance(int index) {
        if (CollectionUtils.isEmpty(INSTANCES)) {
            throw new BusinessException("未找到可用的Netty服务");
        }
        if (INSTANCES.size() <= index) {
            index = index % INSTANCES.size();
        }
        return INSTANCES.get(index);
    }

    /**
     * 轮训策略
     *
     * @return
     */
    public static Instance rt() {

        int index = rtCount.incrementAndGet();
        return RouterTable.getInstance(index);
    }

    /**
     * ip hash 取模
     *
     * @param clientIp
     * @return
     */
    public static Instance ipHash(String clientIp) {

        if (CollectionUtils.isEmpty(INSTANCES)) {
            throw new BusinessException("未找到可用的Netty服务");
        }
        if (StringUtils.isEmpty(clientIp)) {
            return rt();
        }
        return getInstance(clientIp.hashCode() % INSTANCES.size());
    }
}
